/*
 * image_app.hpp
 *
 *  Created on: May 16, 2010
 *      Author: jlapointe
 */

#if !defined(IMAGE_APP_HPP_)
#define IMAGE_APP_HPP_

#define cimg_display 0
//#include <CImg.h>
#include <string>

namespace TestAppFftLib
{

enum ImageType
{
   ImageOne, ImageTwo
};

class ImageApp
{
private:
   bool isImageOneLoaded_;
   bool isImageTwoLoaded_;
   bool isFftInitialized_;
   std::string *imageDirectory_;
   //   cimg_library::CImg<int> *imageOne_;
   //   cimg_library::CImg<int> *imageTwo_;
   int * image1ul_;
   int * image2ul_;

   static const int numberOfRows_ = 128;
   static const int numberOfColumns_ = 128;
   static const int imageArea_ = 16384;
   static const int windowMaxMoveUd_ = 8;
   static const int windowMaxMoveLr_ = 8;
   static const int windowWidth_ = 64;
   static const int windowArea_ = windowWidth_ * windowWidth_; // 4096
   static const int log2WindowArea_ = 12;
   static const int complexWindowWidth_ = 2 * windowWidth_; // 128
   static const int complexWindowArea_ = 2 * windowArea_; // 8192
   static const int zeroPadWidth_ = 8;
   static const int maxPower_ = 6;
   static const int dri_ = 5;
   static const int drj_ = 5;
   static const float factor_;

   int imageOne_[imageArea_];
   int imageTwo_[imageArea_];
   float twoD_Hanning_[windowArea_];
   float correlationSurface_[complexWindowArea_];
   int bitReverseTable1D_[complexWindowWidth_];
   int bitReverseTable2D_[complexWindowArea_];
   float regHpFilter_[complexWindowArea_];
   static const unsigned int nn_[2];
   static const float demeanReg_[25];

   std::string *slashCharacter_;

public:
   ImageApp();

   static const char * const BasicFftDataName;
   static const char * const BasicReduxFftDataName;
   static const char * const BasicReduxFftComplexDataName;
   static const char * const BasicRadix2DataName;
   static const char * const FftwDataName;

   void loadImage(ImageType imageType, const char * const imagePath);

   void executeBasicFft();

   void executeBasicReduxFft();

   void executeBasicReduxComplexFft();

   void executeRadix2Fft();

   void executeFftw();

   bool getAllImagesLoaded();

   void setImageDirectory(const char * const imageDirectory);

   void writeData();

   //
   // Writes the resultantImage to a file
   // NOTE filename is appended to the imageDirectory.
   //
   void writeData(const char * const filename);

   void writeImageSourceData();

   void writeImageSourceData(const char * const filename, int *data);

private:
   int registrationTruncateOffset(int offset, int maxMove);
   void registrationReturnUpperLeft(int rowOffset, int colOffset,
         int *upperLeft);
   int findMin(int argOne, int argTwo);
   int findMax(int argOne, int argTwo);
};

}

#endif /* IMAGE_APP_HPP_ */
